import * as vscode from "vscode";
import { getEOL, getIndentation, isValidClassDeclaration, matchClassDeclaration, removeAfterEqual } from "../utils/utils";
import { FunctionInfo } from "../entities/types";
import { TreeSitter } from "../../../../core/treesitter/TreeSitter";
import Parser from "web-tree-sitter";
import { Logger } from '../../../../src/logger/Logger';

export class FuncBasicInfoProcessor {
  public static async extract(doc: vscode.TextDocument, pos: vscode.Position, range: vscode.Range) {
    const text = doc.getText(range);
    const index = text.indexOf("{");
    // 当函数签名换行时，去除换行以及前后多余的空格
    const signature = text
      .slice(0, index)
      .split(getEOL(doc))
      .map((e: string) => e.trim())
      .join(" ")
      .trim();
    const body = text.slice(index, undefined);

    const functionInfo: FunctionInfo = {
      code: this.extractFunction(doc, range),
      returnTypeName: undefined,
      sourceClassName: undefined,
      sourceFuncName: undefined,
      paramTypeName: [],
      paramName: [],
      memberVariables: new Set(),
      identifiers: new Set(),
      signature: signature,
    };
    this.parseSignature(doc, signature, functionInfo);
    this.getMemberVariables(body, functionInfo);
    this.getAllIdentifiers(body, functionInfo);
    if (!functionInfo.sourceClassName) {
      functionInfo.sourceClassName = this.getClassName(doc, range);
    }
    return functionInfo;
  }
  /**
   * 获取当前函数所有内容
   *
   * @public
   * @param {vscode.TextDocument} doc
   * @param {vscode.Range} range
   * @returns {string}
   */
  public static extractFunction(doc: vscode.TextDocument, range: vscode.Range): string {
    try {
      // 检查range是否有效
      if (!range || range.start.line >= doc.lineCount) {
        return doc.getText(range);
      }

      // 检查上一行是否存在
      const prevLineExists = range.start.line > 0;
      const prevLineNumber = range.start.line - 1;

      // 只有当上一行存在时才检查模板语法
      if (prevLineExists) {
        try {
          const prevLineText = doc.lineAt(prevLineNumber).text;
          if (/\s*template\s*<[\s\S]*>/g.test(prevLineText)) {
            return doc.getText(new vscode.Range(new vscode.Position(prevLineNumber, 0), range.end));
          }
        } catch (error) {
          // 如果获取上一行内容失败，继续使用原始范围
          Logger.warn(`Failed to check template syntax:${error}`);
        }
      }
      // 默认返回原始范围的文本
      return doc.getText(new vscode.Range(new vscode.Position(range.start.line, 0), range.end));
    } catch (error) {
      Logger.error(`Error in extractFunction: ${error}`);
      // 发生错误时返回空字符串或原始范围的文本
      return doc.getText(range);
    }
  }

  public static parseSignature(doc: vscode.TextDocument, signature: string, functionInfo: FunctionInfo) {
    const tree = TreeSitter.getInstance().getTree(signature + " {}", doc.languageId);
    if (tree) {
      // 提供一个空实现，使以下两种情况都被解析成function_declarator，否则
      // sptr<IRemoteBroker> IRemoteObject::AsInterface(int A, int B) 会被解析成 function_declarator
      // sptr<IRemoteBroker> IRemoteObject::AsInterface() 会被解析成 init_declarator
      const rootNode = tree.rootNode;
      const { paramTypes, paramNames, paramList } = this.getParamTypeAndName(rootNode);
      const returnType = this.getReturnType(rootNode);
      const sourceClass = this.getSourceClassName(rootNode);
      const functionName = this.getFunctionName(rootNode);
      functionInfo.paramTypeName = paramTypes;
      functionInfo.paramName = paramNames;
      functionInfo.paramList = paramList;
      functionInfo.returnTypeName = returnType;
      functionInfo.sourceClassName = sourceClass;
      functionInfo.sourceFuncName = functionName;
    }
  }

  private static getMemberVariables(body: string, functionInfo: FunctionInfo) {
    const exclude = new Set(functionInfo.paramName);
    // 匹配externalIndex.size、algoImpl_->OnBufferAvailable、externalIndex[blockIndex]、ApplyGain(sample, gain_)
    let re = /(?<variable>\w+)/g;
    let match: RegExpExecArray | null;
    while ((match = re.exec(body))) {
      const variable = match.groups?.variable;
      if (variable && !exclude.has(variable) && isNaN(Number(variable))) {
        functionInfo.memberVariables?.add(variable);
      }
    }
  }

  private static getAllIdentifiers(body: string, functionInfo: FunctionInfo) {
    let re = /(?<identifier>\w+)/g;
    let match: RegExpExecArray | null;
    while ((match = re.exec(body))) {
      const identifier = match.groups?.identifier;
      if (identifier && isNaN(Number(identifier))) {
        functionInfo.identifiers?.add(identifier);
      }
    }
  }

  private static getClassName(document: vscode.TextDocument, functionRange: vscode.Range): string {
    try {
      return this.extractClassNameFromText(document, functionRange);
    } catch (error) {
      return "";
    }
  }
  /**
   * 使用更准确的文本处理方式提取类名
   * @param document VS Code 文档对象
   * @param functionRange 选中的函数范围
   * @returns 找到的类名，如果不在类中则返回空字符串
   */
  private static extractClassNameFromText(document: vscode.TextDocument, functionRange: vscode.Range): string {
    const documentText = document.getText();
    const lines = documentText.split("\n");
    // 获取函数开始位置的缩进级别
    const functionLine = lines[functionRange.start.line];
    const functionIndentation = getIndentation(functionLine);
    // 向上搜索可能的类声明
    let bracketCount = 0;
    let insideClass = false;
    let potentialClassName = "";

    for (let i = functionRange.start.line; i >= 0; i--) {
      const line = lines[i].trim();
      const currentIndentation = getIndentation(lines[i]);
      // 计算花括号的嵌套层级
      if (line.includes("{")) {
        bracketCount--;
      }
      if (line.includes("}")) {
        bracketCount++;
      }
      // 如果到达了更外层的作用域，重置状态
      if (bracketCount > 0) {
        insideClass = false;
        potentialClassName = "";
        continue;
      }
      // 检查是否是类声明
      const classMatch = matchClassDeclaration(line);
      if (classMatch) {
        // 验证这是否是一个真实的类声明而不是注释或字符串
        if (isValidClassDeclaration(lines[i])) {
          // 检查缩进层级来确保函数确实属于这个类
          if (currentIndentation < functionIndentation) {
            potentialClassName = classMatch[1];
            insideClass = true;
            break;
          }
        }
      }
    }
    return insideClass ? potentialClassName : "";
  }

  public static getParamTypeAndName(node: Parser.SyntaxNode): {
    paramTypes: string[];
    paramNames: string[];
    paramList: string[];
  } {
    let paramTypes: string[] = [];
    let paramNames: string[] = [];
    let paramList: string[] = [];
    const paramters = node.descendantsOfType(["parameter_declaration", "optional_parameter_declaration"]);
    paramters.forEach((param: any) => {
      const ptypes = param.descendantsOfType("type_identifier").map((n: any) => n.text);
      const pdeclar = param.childForFieldName("declarator")?.descendantsOfType("identifier");
      paramTypes.push(...ptypes);
      paramList.push(removeAfterEqual(param.text));
      if (pdeclar?.length) {
        paramNames.push(pdeclar[0].text);
      }
    });
    return { paramTypes, paramNames, paramList };
  }

  public static getReturnType(rootNode: Parser.SyntaxNode): string | undefined {
    // 由于添加了 {}，根节点应该是 translation_unit
    // 获取 function_definition 节点
    const functionDef = rootNode.children.find((child: any) => child.type === "function_definition");

    if (!functionDef) {
      return undefined;
    }

    let returnTypeStr = "";
    let foundQualifier = false;

    // 遍历函数定义的直接子节点
    for (const child of functionDef.children) {
      // 跳过函数体
      if (child.type === "compound_statement") {
        continue;
      }

      // 处理模板返回类型，如 sptr<IRemoteBroker>
      if (child.type === "template_type") {
        const typeIdentifier = child.children.find((c: any) => c.type === "type_identifier");
        const templateArgs = child.children.find((c: any) => c.type === "template_argument_list");

        if (typeIdentifier) {
          returnTypeStr += typeIdentifier.text;
        }
        if (templateArgs) {
          returnTypeStr += "<" + templateArgs.text + ">";
        }
        foundQualifier = true;
        continue;
      }

      // 处理基本类型和自定义类型
      if (child.type === "primitive_type" || child.type === "type_identifier") {
        returnTypeStr += child.text;
        foundQualifier = true;
        continue;
      }

      // 处理命名空间或类限定符
      if (child.type === "qualified_identifier") {
        const parts: string[] = [];
        for (const part of child.children) {
          if (part.type === "namespace_identifier" || part.type === "type_identifier") {
            parts.push(part.text);
          }
        }
        returnTypeStr += parts.join("::");
        foundQualifier = true;
        continue;
      }

      // 如果已经找到了类型限定符，并且遇到了其他节点，就停止处理
      if (foundQualifier && (child.type === "function_declarator" || child.type === "identifier")) {
        break;
      }
    }

    return returnTypeStr || undefined;
  }

  private static getSourceClassName(node: Parser.SyntaxNode): string | undefined {
    const functionDefinition = node.descendantsOfType("function_declarator");
    for (const func of functionDefinition) {
      const res = func.childForFieldName("declarator")?.descendantsOfType("namespace_identifier");
      if (res?.length) {
        return res[res.length - 1].text;
      }
    }
    return undefined;
  }

  public static getFunctionName(node: Parser.SyntaxNode): string | undefined {
    const functionDefinition = node.descendantsOfType("function_declarator");
    for (const func of functionDefinition) {
      const res = func.childForFieldName("declarator")?.descendantsOfType("identifier");
      if (res?.length) {
        return res[0].text;
      }
    }
    return undefined;
  }
}